#pragma once
#include <iostream>  
#include <string>
#include "CommonDataType.h"
#include "EventStorage.h"
#include "ThrowErrorCode.h"
#include "TECommonFunctions.h"
#include "Stdtosys.h"

using std::string;
using StringManipulator::NULL_STRING;

class OutputDisplay{

private:
    /////string allText;
    string upcomingText;
	vector<Event> const * _eventList;
	//string bottomText;
    /////string todayText;
    /////string weekText;
    /////string floatingTasksText;
    /////string pastEntriesText;
    /////string labelText;
	//static String^ convertToSystemString(string toBeConverted);
	/////const string helpText="expected input: help command\n"+"like 'help add' for add format, supporting commands: add, delete, display, edit, undo\n";
	/////const string helpAdd="expected input: add content\n"+"add 'generatedindex content' to issues.\n";
	/////const string helpDelete="expected input: delete index/indices\n"+"display all the 'generatedindex content'\n";
	/////const string helpDisplay="expected input: display\n"+"add 'generatedindex content' to issues.\n";
	/////const string helpModify="expected input: edit indextobeedit new content\n"+"replace the old content at the index with new content\n";
	/////const string helpUndo="expected input: undo\n"+"cancel last command\n";
	/////const string Added="added successfully\n";
	/////const string Deleted="deleted successfully\n";
	/////const string Displayed="displayed successfully\n";
	/////const string Modified="added successfully\n";
    /////const string Undid="undo successfully\n";	
	
	OutputDisplay();
	OutputDisplay (const OutputDisplay&);
	void operator= (const OutputDisplay& );
public:
	static OutputDisplay& get();
	
	//static DisplayText* getDisplayPointer();
	//string converttoString(pos_int index); //n
	void displayEvents(vector<pos_int> _IDList); 
	void showAdded(string detailAdded);
	void showdeleted(vector<pos_int> _IDDeleted,vector<pos_int> _IDIllegal);
	void showModified(pos_int _IDModified);
	void getToModify(pos_int _IDToModify);
	/////void readAllText(EventVector* _eventList); 
	/////void readTodayText(EventVector* _eventList); 
	/////void readWeekText(EventVector* _eventList); 
	/////void readFloatingTasksText(EventVector* _eventList); 
	/////void readPastOperationsText(EventVector* _eventList); 
	/////void readLabelText(EventVector* _eventList); 
    //string getUpcomingText();
    String^ getUpcomingText();
    //string getbottomText();
	/////static string getAllText();
	/////static string getTodayText();
	/////static string getWeekText();
	/////static string getFloatingTasksText();
	/////static string getPastOperationsText();
	/////static string getLabelText();
	/////string showHelp();//="expected input: help command\n"+"like 'help add' for add format, supporting commands: add, delete, display, edit, undo\n";
	/////string showHelpAdd();//="expected input: add content\n"+"add 'generatedindex content' to issues.\n";
	/////string showHelpDelete();//="expected input: delete index/indices\n"+"display all the 'generatedindex content'\n";
	/////string showHelpDisplay();//="expected input: display\n"+"add 'generatedindex content' to issues.\n";
	/////string showHelpModify();//="expected input: edit indextobeedit new content\n"+"replace the old content at the index with new content\n";
	/////string showHelpUndo();//="expected input: undo\n"+"cancel last command\n";
	/////string showAdded();//="added successfully\n";
	/////string showDeleted();//="deleted successfully\n";
	/////string showDisplayed();//="displayed successfully\n";
	/////string showModified();//="modifided successfully\n";
    /////string showUndid();//="undo successfully\n";	
};

typedef OutputDisplay * const ReadOutputDisplay;

//Start of constant list->
con_str SPACE_STRING = " ";
con_str SPACE_COMMA_SPACE = ", ";
con_str SUPER_SPACE_STRING = "  ";
con_str NEW_LINE = "\r\n";
con_str STRING_YES = "YES";
con_str STRING_NO = "NO";
con_str STRING_START_WITH_COLON = "Start: ";
con_str STRING_END_WITH_COLON = "End: ";
con_str STRING_TIME_WITH_COLON = "Time: ";
con_str STRING_REMIND_WITH_COLON = "Remind: ";
con_str STRING_IS_DONE = "Is done? ";
con_str STRING_FLOATING = "Floating";
con_str STRING_IS_REMINDED = "Already reminded? ";
con_str STRING_DOT_SPACE = ". ";
con_str STRING_QUOTATION = "'";
con_str STRING_ADDED = "added successfully";
con_str STRING_MODIFIED = "event at following indix modified successfully: ";
con_str STRING_DELETED = "events at following indices deleted: ";
con_str STRING_NOT_DELETED = "following indices are illegal and not deleted: ";
con_str STRING_EMPTY_NO_DELETE = "record empty, nothing to delete unless something is added";
const pos_int EVERYDAY_INDICATOR = 1;
//<-End of constant list

static string toStringOfRepeatRule (const RepeatRule theRule) {
	string result = STRING_EVERY[0] + SPACE_STRING;
	if (theRule.startOfWeek != WeekDay::UNCLEAR) {
		result += capitaliseFirst(WEEKDAY_LIST[(pos_int)(theRule.startOfWeek)][0]);
		return result;
	}
	switch (theRule.frequency)
	{
	case RepeatFrequency::EVERY_N_DAY:
		if (theRule.period == EVERYDAY_INDICATOR) {
			result += STRING_DAY[0];
		}
		else {
			result += theRule.period;
			result += SPACE_STRING;
			result += STRING_DAY[1];
		}
		break;
	case RepeatFrequency::EVERY_MONTH:
		result += STRING_MONTH[0];
		break;
	default:
		failProgram (ERR_OutputDisplay::RepeatRule_ghost);
		break;
	}
	return result;
}

static string outputBool (const bool theBool) {
	if (theBool) {
		return STRING_YES;
	}
	else {
		return STRING_NO;
	}
}
static string toStringOfEvent(const Event& theEvent) {
	string result = NULL_STRING; 
	result += theEvent.getDetails();
	result += SUPER_SPACE_STRING;
	if (theEvent.isDuration()) {
		result += STRING_START_WITH_COLON;
		result += theEvent.getStartTime().toTimeString();
		result += SPACE_STRING;
		result += theEvent.getStartTime().toDateString();
		result += SPACE_STRING;
		result += theEvent.getStartTime().toDayOfWeekString();
		result += SUPER_SPACE_STRING;
		result += STRING_END_WITH_COLON;
		result += theEvent.getEndTime().toTimeString();
		result += SPACE_STRING;
		result += theEvent.getEndTime().toDateString();
		result += SPACE_STRING;
		result += theEvent.getStartTime().toDayOfWeekString();
	}
	else {
		result += STRING_TIME_WITH_COLON;
		result += theEvent.getStartTime().toTimeString();
		result += SPACE_STRING;
		result += theEvent.getStartTime().toDateString();
		result += SPACE_STRING;
		result += theEvent.getStartTime().toDayOfWeekString();
	}

	if (theEvent.getRepeatRule().frequency != RepeatFrequency::NO_REPEAT ) {
		result += SUPER_SPACE_STRING;
		result += toStringOfRepeatRule (theEvent.getRepeatRule());
	}

	result += NEW_LINE;
	if (theEvent.getRemindTime().isEmpty() == false) {
		result += STRING_REMIND_WITH_COLON;
		result += theEvent.getRemindTime().toTimeString();
		result += SPACE_STRING;
		result += theEvent.getRemindTime().toDateString();
		result += SPACE_STRING;
		result += theEvent.getRemindTime().toDayOfWeekString();
		result += SUPER_SPACE_STRING;
	}

	result += STRING_IS_DONE;
	result += outputBool(theEvent.getIsDone());
	result += SUPER_SPACE_STRING;
	result += STRING_IS_REMINDED;
	result += outputBool (theEvent.getIsReminded());
	
	if (theEvent.isFloating() == true) {
		result += SUPER_SPACE_STRING;
		result += STRING_FLOATING;
	}

	result += NEW_LINE;

	return result;
}

